package club.jdiy.admin.util;

import club.jdiy.core.ex.JDiyException;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;

/**
 * 字符串Id值生成器
 *
 * @version 20150507
 */
public class IdUtil {
    /**
     * 为便于以后扩展升级(NOSQL/分布式)，建议ID用字符串形式．
     * 这是一个临时解决方案，不适用于高并发的newId()值创建．
     * <p/>
     * <p/>
     * 生成一个新的id值. 系统保证返回的值为整库唯一。
     *
     * @return String 新生成的id值. 该值为10个字符的定长字符串
     */
    public static String newId() throws JDiyException {
        String ident = Encoding("0123456789abcdefghijklmnopqrstuvwxyz".toCharArray(), getTimes());
        switch (ident.length()) {
            case 9:
                return "z" + ident;
            case 8:
                return "z0" + ident;
            case 7:
                return "z00" + ident;
            case 6:
                return "z000" + ident;
            default:
                throw new JDiyException("对不起,服务器上的时间设置无效,无法生成ID,请校正服务器的时间后重试.");
        }
    }

    public synchronized static long getTimes() {
        long L = System.currentTimeMillis();
        while (L == System.currentTimeMillis()) {
            L = System.currentTimeMillis(); //不能移到while外,proguard优化后会把while语句去掉，造成id重复。
        }
        return L;
    }

    private static String Encoding(char[] jz, long n) {
        long s = n / 36,
                y = n % 36;
        int sInt = (int) s,
                yInt = (int) y;
        if (s < 36) {
            return (sInt == 0 ? "" : String.valueOf(jz[sInt])) + jz[yInt];
        } else {
            return Encoding(jz, s) + jz[yInt];
        }
    }

    /**
     * YYYYmmddHHmmss+3位数字
     */
    public static String getNows() {
        String suf = "" + getTimes()%1000;
        if (suf.length() == 1) suf = "00" + suf;
        else if (suf.length() == 2) suf = "0" + suf;
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) + suf;
    }

    public static void main(String[] args) {
        for(int i=0;i<10;i++){
            Runnable r = new Runnable() {
                @Override
                public void run() {
                    for(int i=0;i<10;i++){
                        System.out.println(getNows());
                    }
                }
            };
            new Thread(r).start();
        }
    }

    /**
     * 生成支付流水号
     *
     * @return 支付流水号
     */
    public synchronized static String newLshId() {
        String suf = String.valueOf(getTimes() % 1000);
        if (suf.length() == 1) suf = "00" + suf;
        else if (suf.length() == 2) suf = "0" + suf;
        return new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + suf;

    }
}
